#include "Game.h"
#include <iostream>
#include <Windows.h>
#include "WorldBuilder.h"
#include "StandardWorldBuilder.h"

#define DELAY 0.030
#define MAX_VELOCITY 120

Game::Game(sf::RenderWindow* window, StateMachine* state_machine) : _window(window), GameState(state_machine), _nbFrame(0), _level(1)
{
}

Game::~Game(){
	GameState::~GameState();
	delete myAvatar;
	delete myWorld;
	delete myHud;
}

void Game::init()
{
	//Create world
	buildNewWorld(3);
	_soundManager.playSound(next_level);
	//Create avatar
	myAvatar= new Avatar(Vector2f(36,36), sf::Color(sf::Color::Blue), Vector2f(0,0),myWorld->getStartingPosition(), myWorld->_MovableManager->_animationHandlerFactory);
	//HUD

	myHud= new HUD(*myAvatar);

	//creates the ViewManager
	myCamera= new ViewManager(myAvatar->getShape(), _window, 150);
}

void Game::gameLoop()
{
        // Get delta time for frame-rate depended movement
        
		if (frametime.getElapsedTime().asSeconds()>DELAY)
		{
		float dt = frametime.restart().asSeconds();
        // Event handling
        handleEvents();
		//move the player
		//cout<<"dt "<<dt<<endl;
		if(dt>DELAY) {dt=DELAY;}
		myAvatar->move(dt);
		myWorld->_MovableManager->moveMovables(dt);

		// Manage the collision with an ennemy and play the appropriate sound
		hitResult res=myWorld->_MovableManager->resolveMovableCollision(myAvatar);
		if(res==Fail)
			_soundManager.playSound(ghost_laugh);
		else if(res==Success)
			_soundManager.playSound(ghost_die);
		
		myAvatar->_touching=false;
		if(myWorld->collides(*myAvatar))
		{
			//myAvatar._touching=true;
		while(myWorld->collides(*myAvatar)) {}//resolve all the conflicts
		}
		
		//Manage the collision with an item and play the appropriate sound
		collectResult resc=myWorld->collectItems(*myAvatar);
		if (resc==good_item) {_soundManager.playSound(collect);}
		else if (resc==bad_item) {_soundManager.playSound(damage);}
		}
		else
		{
			Sleep(DELAY - frametime.getElapsedTime().asSeconds());
		}
		float current=frametime.getElapsedTime().asMilliseconds();
		//std::cout<<current<<std::endl;
}

void Game::handleEvents()
{
	sf::Event event;
        while(_window->pollEvent(event))
        {
            if(event.type == sf::Event::Closed)
                _window->close();
			if (event.type == sf::Event::Resized) {_window->setSize(Vector2u(800,600));}
        }

		myAvatar->slowDown();
		// Horizontal movement
        if(sf::Keyboard::isKeyPressed(sf::Keyboard::Left))
			myAvatar->setVelocity(Vector2f(-MAX_VELOCITY,myAvatar->getVelocity().y));
        else if(sf::Keyboard::isKeyPressed(sf::Keyboard::Right))
            myAvatar->setVelocity(Vector2f(MAX_VELOCITY,myAvatar->getVelocity().y));

		// Jumping
        if(sf::Keyboard::isKeyPressed(sf::Keyboard::Space) && myAvatar->_touching)
		{
			myAvatar->setVelocity(Vector2f(myAvatar->getVelocity().x,-400));
			_soundManager.playSound(jump);
		}
}

void Game::draw()
{
	_window->clear();
	myWorld->draw(*_window, myCamera->getView().getCenter());
	if( !myAvatar->isInvicible() || _nbFrame%3==0) {myAvatar->draw(*_window);}
	_window->setView(myCamera->getView());
	myHud->draw(*_window);
	if(_nbFrame%5==0)
	{
		myAvatar->updateAnimation();
		myWorld->_MovableManager->updateMovables();
	}
	_nbFrame=(_nbFrame+1)%5;
}

void Game::pause()
{}

void Game::update()
{
	gameLoop();
	draw();
	myCamera->follow_target();
	if(myWorld->levelCompleted(*myAvatar))
	{
		if(_level==3)
			_state_machine->changeState(state::victory);
		else
		{	_level++;
			delete myWorld;
			buildNewWorld(_level);
			myAvatar->getShape()->setPosition(myWorld->getStartingPosition());
			_soundManager.playSound(next_level);
		}
	}
	else if(myWorld->limitReached(*myAvatar) || myAvatar->get_nb_heart()<=0)
	{
		myAvatar->loseLife();
		delete myWorld;
		buildNewWorld(_level);
		myAvatar->getShape()->setPosition(myWorld->getStartingPosition());
		_soundManager.playSound(death);
	}
	else if(myAvatar->isDead())
	{
		_state_machine->changeState(state::gameover);
	}
	else if(myAvatar->get_nb_gold()>=5)
	{
		myAvatar->set_gold(0);
		myAvatar->add_life();
		_soundManager.playSound(up);
	}
}
void Game::exit()
{

}

void Game::buildNewWorld(int numLevel)
{
	WorldBuilder* standardWorldBuilder= new StandardWorldBuilder();
	standardWorldBuilder->createNewWorld();
	standardWorldBuilder->buildTextures();
	standardWorldBuilder->buildLevel(numLevel);
	standardWorldBuilder->buildGravity();
	myWorld=standardWorldBuilder->getWorld();
}